import datetime
import re

from django.shortcuts import render, redirect
# 导包
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
# 导入类视图
from django.views import View

# from myapp.models import User
import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
# 导入加密库
import hashlib
# 导入图片库
# 绘画库
from PIL import ImageDraw
# 字体库
from PIL import ImageFont
# 图片库
from PIL import Image
# 随机库
import random
# 文件流
import io

import requests

# 导入上传文件夹配置
from mydjango123.settings import UPLOAD_ROOT
import os

# 导入原生sql模块
from django.db import connection

import jwt

# 导入redis数据库
import redis

# 导入时间模块
import time

# 导入公共目录变量
from mydjango123.settings import BASE_DIR

# 导包
from django.db.models import Q, F

# 导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid
from myapp.models import *
from django.utils.deprecation import MiddlewareMixin
import pymongo
from myapp.serializers import *
r = redis.Redis('localhost', 6379)
conn = pymongo.MongoClient('localhost', 27017)
db = conn.md
table = db.goods_img

# 回复功能
class Rep_comment(APIView):
    def get(self,request):
        cid = request.GET.get('cid', None)
        uid = request.GET.get('uid', None)
        content = request.GET.get('content', None)

        comment = Comment.objects.get(pk=cid)
        # 看是否存在回复的评论
        alist=[]
        if comment.reply:
            # 转换为列表格式
            alist = eval(comment.reply)
            # 向第一个插入
            alist.insert(0,{'uid':uid,'content':content})
        else:
            # 正常插入
            alist.insert(0,{'uid':uid,'content':content})
        print(json.dumps(alist,ensure_ascii=False))
        # 更新保存
        comment.reply=json.dumps(alist,ensure_ascii=False)
        comment.save()
        return Response({'code':200,'msg':'回复成功'})
# 商品评论
class CommentInsert(APIView):
    conn = pymongo.MongoClient('localhost', 27017)
    db = conn.md
    table = db.comment
    def get(self,request):
        gid = request.GET.get('gid',None)
        print(gid)
        # comments = self.table.find({'gid':gid},{'_id':0}).sort([("_id",pymongo.DESCENDING)])
        # comments = self.table.find({'gid':gid},{'_id':0}).sort([("_id",pymongo.DESCENDING)])
        comments=Comment.objects.filter(gid= gid).all().order_by('-id')
        users= User.objects.values('id','username')
        user_ser=Usertestser(users,many=True)
        comment_Ser= CommentSer(comments,many=True)

        # return Response({'code':200,'data':list(comments)})
        return Response({'code':200,'data':comment_Ser.data,'udata':users})

    def post(self,request):
        # 获取客户端ip
        if 'HTTP_X_FORWARDED_FOR' in request.META:
            ip = request.META.get('HTTP_X_FORWARDED_FOR')
        else:
            ip= request.META.get('REMOTE_ADDR')
        print(ip)
        # 30 秒内只能评论三次
        try:
            if r.llen(ip)>3 :
                return Response({'code':403,'msg':'您评论过快'})
        except Exception as e:
            pass

        try:
            self.table.insert({
                'username': request.POST.get('username',None),
                'gid':request.POST.get('gid'),
                'content':request.POST.get('content'),
            })
            r.lpush(ip, 1)
            r.expire(ip, 30)
        except :
            pass
        # 初始化参数
        # comment = CommentSer(data=request.data)
        # 验证字段
        # if comment.is_valid():
            # 进行入库操作
            # comment.save()
            # 设置评论间隔
            # r.lpush(ip,1)
            # r.expire(ip,30)

        return Response({'code':200,'msg':'评论成功'})

# 商品详情页
class Goodinfo(APIView):
    def get(self,request):
        id=request.GET.get('id')
        goods=Goods.objects.get(pk=id)
        # 判断是否有详情图片
        info_img=[]
        info_video=''
        if goods.info_imgs ==1:
            info_img=table.find_one({"name":goods.name})['imgs']
            info_video=table.find_one({"name":goods.name})['video']
        goods_ser=GoodslSer(goods)

        return Response({"data":goods_ser.data,"info_imgs":info_img,'info_video':info_video})

# 搜索接口
class Search(APIView):
    def get(self,request):
        # 检索字段
        text = eval(request.GET.get('text',None))
        # 建立游标对象

        sql=""
        for val in text:
            # 拼接sql语句
            sql += "or name like '%%%s%%'"%val

        cursor=connection.cursor()
        # 执行sql
        cursor.execute("select name,id,img,price from goods where %s"%sql[2:])
        # 查询
        res=dictfetch(cursor)
        count=len(res)
        return Response({'msg':text,"data":res,'total':count})

#  格式化结果集
def dictfetch(cursor):
    # 声明描述符 description 字段名
    desc= cursor.description
    # 重组结果
    return [dict(zip([col[0] for col in desc],row))
        for row in cursor.fetchall()
    ]

# 商品列表页
class GoodsList(APIView):
    def get(self,request):
        # 检索字段
        text = request.GET.get('text',None)
        # 排序字段
        column = request.GET.get('column',None)
        sort_order = request.GET.get('order',"")

        # 当前页
        page = int(request.GET.get('page',1))
        # 一页显示个数
        size = int(request.GET.get('size',1))
        # 计算从哪开始切
        data_start = (page-1)*size
        # 计算切到哪
        data_end = page * size
        # 查询操作
        if column:
            goods= Goods.objects.all().order_by(sort_order+column)[data_start:data_end]
        else:
            goods= Goods.objects.all()[data_start:data_end]
        # 是否进行模糊查询
        if text:
            goods=[]
            # 循环条件列表
            for key in text:
                # 查询数据
                good_obj=Goods.objects.filter(Q(name__contains=key)|Q(desc__contains=key)).all()[data_start:data_end]
                # 向列表尾部拼接
                goods.extend(good_obj)
            # goods=Goods.objects.filter(Q(name__contains=key)|Q(desc__contains=key)).all()[data_start:data_end]
            # count = Goods.objects.filter(Q(name__contains=text)|Q(desc__contains=text)).count()
            # 去重 防止重复
            goods=list(set(goods))
            count = len(goods)
        else:
            # 查询所有商品个数
            count = Goods.objects.count()

        goods_ser=GoodslSer(goods,many=True)

        page_list=[]
        if (count % size)%2==0:
            page_list=[i for i in range(1,count % size+1)]
        else:
            page_list=[i for i in range(1,count % size+2)]

        return Response({'data':goods_ser.data,'total':count,'page_list':page_list})

# 商品分类接口
class CategoryList(APIView):
    def get(self,request):
        category=Category.objects.all()
        category_Ser=CategorySer(category,many=True)
        return Response(category_Ser.data)

# 商品入库接口
class InsertGoods(APIView):

    def post(self,request):
        # 接参
        name = request.POST.get('name',None)
        cid = request.POST.get('cid',None)
        price = request.POST.get('price',None)
        params = request.POST.get('params',None)
        # 获取详情图片的列表
        imgs_name = request.POST.getlist('imgs_name',None)

        # 排重操作
        mygoods=Goods.objects.filter(name=name).first()
        if mygoods:
            return Response({"code":403,"msg":'已存在该商品'})
        # 入库
        try:
            goods=Goods(name=name,price=price,params=params,cid=cid)
            # 将参数存入redis
            r.hmset(name,json.loads(params))
            # 如果存在详情图片
            if imgs_name:
                for i in imgs_name:
                    myfile = request.FILES.get(i)
                    print(myfile.name)
                    # 保存详情图
                    with open(os.path.join(UPLOAD_ROOT, '', myfile.name), 'wb')as f:
                        for chunk in myfile.chunks():
                            f.write(chunk)
                table.insert({'name': name, 'imgs': imgs_name})
                goods.info_imgs = 1

            goods.save()
        except Exception as e:
            return Response({"code":403,"msg":'添加失败'})

        return Response({"code": 200, "msg": '添加成功'})